{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-04-27T11:30:07.839711Z",
     "start_time": "2025-04-27T11:30:07.827620Z"
    }
   },
   "source": [
    "import torch\n",
    "from sympy import false\n",
    "from torch import nn\n",
    "from torch.nn import functional as F\n",
    "\n",
    "net = nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))\n",
    "\n",
    "X = torch.rand(2, 20)\n",
    "net(X)"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[-0.0153, -0.0365,  0.0457, -0.1204,  0.1603, -0.1237, -0.0100,  0.1151,\n",
       "         -0.0877,  0.2251],\n",
       "        [-0.0440, -0.0131,  0.0450, -0.2204,  0.0978, -0.2301,  0.1246,  0.0273,\n",
       "         -0.0507,  0.1295]], grad_fn=<AddmmBackward0>)"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 78
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T11:30:07.917169Z",
     "start_time": "2025-04-27T11:30:07.903073Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class MLP(nn.Module):\n",
    "\t# 用模型参数声明层。这里，我们声明两个全连接的层\n",
    "\tdef __init__(self):\n",
    "\t\t# 调用MLP的父类Module的构造函数来执行必要的初始化。\n",
    "\t\t# 这样，在类实例化时也可以指定其他函数参数，例如模型参数params（稍后将介绍）\n",
    "\t\tsuper().__init__()\n",
    "\t\tself.hidden = nn.Linear(20, 256)  # 隐藏层\n",
    "\t\tself.out = nn.Linear(256, 10)  # 输出层\n",
    "\n",
    "\t# 定义模型的前向传播，即如何根据输入X返回所需的模型输出\n",
    "\tdef forward(self, X):\n",
    "\t\t# 注意，这里我们使用ReLU的函数版本，其在nn.functional模块中定义。\n",
    "\t\treturn self.out(F.relu(self.hidden(X)))"
   ],
   "id": "33f0c60cb76937",
   "outputs": [],
   "execution_count": 79
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T11:30:07.979976Z",
     "start_time": "2025-04-27T11:30:07.965007Z"
    }
   },
   "cell_type": "code",
   "source": [
    "net = MLP()\n",
    "print(net(X))"
   ],
   "id": "cef9bf3495261fab",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[-0.0200,  0.0523,  0.0903,  0.2072,  0.0674,  0.2689,  0.1518,  0.2602,\n",
      "          0.1665,  0.0590],\n",
      "        [-0.0324, -0.0447,  0.1489,  0.1889, -0.0590,  0.1469,  0.1597,  0.1478,\n",
      "          0.0863,  0.2123]], grad_fn=<AddmmBackward0>)\n"
     ]
    }
   ],
   "execution_count": 80
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T11:30:08.026154Z",
     "start_time": "2025-04-27T11:30:08.010976Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class MySequential(nn.Module):\n",
    "\tdef __init__(self, *args):\n",
    "\t\tsuper().__init__()\n",
    "\t\tfor block in args:\n",
    "\t\t\tself._modules[block] = block\n",
    "\n",
    "\tdef forward(self, X):\n",
    "\t\tfor block in self._modules.values():\n",
    "\t\t\tX = block(X)\n",
    "\t\treturn X\n",
    "\n",
    "\n",
    "net = MySequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))\n",
    "print(net(X))\n"
   ],
   "id": "37294c030f500e9b",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[-0.0844,  0.2032,  0.4205, -0.0953, -0.3842, -0.2294,  0.1605,  0.1492,\n",
      "          0.0330,  0.1246],\n",
      "        [-0.1246,  0.1475,  0.2795, -0.0551, -0.0463, -0.1242,  0.0965,  0.0748,\n",
      "         -0.0566, -0.0095]], grad_fn=<AddmmBackward0>)\n"
     ]
    }
   ],
   "execution_count": 81
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T11:30:08.056251Z",
     "start_time": "2025-04-27T11:30:08.042137Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class FixedHiddenMLP(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        # 不计算梯度的随机权重参数。因此其在训练期间保持不变\n",
    "        self.rand_weight = torch.rand((20, 20), requires_grad=False)\n",
    "        self.linear = nn.Linear(20, 20)\n",
    "\n",
    "    def forward(self, X):\n",
    "        X = self.linear(X)\n",
    "        # 使用创建的常量参数以及relu和mm函数\n",
    "        X = F.relu(torch.mm(X, self.rand_weight) + 1)\n",
    "        # 复用全连接层。这相当于两个全连接层共享参数\n",
    "        X = self.linear(X)\n",
    "        # 控制流\n",
    "        while X.abs().sum() > 1:\n",
    "            X /= 2\n",
    "        return X.sum()"
   ],
   "id": "b01696683410e06d",
   "outputs": [],
   "execution_count": 82
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T11:30:34.097399Z",
     "start_time": "2025-04-27T11:30:34.084814Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class NestMLP(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        self.net = nn.Sequential(nn.Linear(20, 64), nn.ReLU(),\n",
    "                                 nn.Linear(64, 32), nn.ReLU())\n",
    "        self.linear = nn.Linear(32, 16)\n",
    "\n",
    "    def forward(self, X):\n",
    "        return self.linear(self.net(X))\n",
    "\n",
    "chimera = nn.Sequential(NestMLP(), nn.Linear(16, 20), FixedHiddenMLP())\n",
    "chimera(X)"
   ],
   "id": "8916e093fd0cb4cf",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(-0.2902, grad_fn=<SumBackward0>)"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 84
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T11:30:08.150403800Z",
     "start_time": "2025-04-27T11:16:31.062978Z"
    }
   },
   "cell_type": "code",
   "source": "",
   "id": "149c02ec30ea44f4",
   "outputs": [],
   "execution_count": null
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
